package org.kinglone.common.pager;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;


public class PageTag extends TagSupport{
	
	private Integer pageIndex;//当前页码
	private Integer pageSize;//每页显示数量
	private Integer recordCount;//总记录数
	private String submitUrl;//提交的地址   index.action?pageIndex={0}
	
	private String pageStyle;//标签类型，可以在页面修改标签类型
	
	//将占位符"{0}"定义为常量
	private final String TAG = "{0}";
	
	@Override
	public int doStartTag() throws JspException {
		//System.out.println("----doStartTag---");
		//定义写回jsp页面
		JspWriter write = this.pageContext.getOut();
		
		//使用StringBuffer用于拼接字符串
		StringBuffer sf = new StringBuffer();
		
		try {
			//判断总记录数是否大于0
			if(this.recordCount > 0){
				/**
				 * 计算总页码值 
				 * 总数取余每页显示数量，整除:结果为总页码值;有余数，则总页码值为商加1
				 */
				int totalPageNum = this.recordCount % this.pageSize == 0? this.recordCount/this.pageSize : this.recordCount/this.pageSize+1;  
			    //定义跳转路径
				String jumpUrl ="";
				/**
				 * 假设当前页码在第一页，则"上一页"不可点击
				 * 拼接"上一页"
				 */
				if(this.pageIndex ==1){
					//上一页
					sf.append("<span class='disabled'>上一页</span>");
					
					/**
					 * 计算中间页码
					 * 带入参数：拼接字符串,总页码值
					 */
					calcMiddlepage(sf,totalPageNum);
					
					/**
					 * 判断下一页是否可以点击  总页码是否等于1
					 * 1、如果只有一页，"下一页"不可以点击，拼接"下一页"
					 * 2、如果不止一页，设置跳转的路径jumpUrl，拼接"下一页"跳转路径
					 */
					if(totalPageNum==1){
						//只有一页  拼接"下一页"
						sf.append("<span class='disabled'>下一页</span>");
					}else{
						/**
						 * 不止一页，设置跳转的路径，拼接'下一页'路径
						 * 跳转路径为提交地址将占位符"{0}"替换成"当前页码"+1,则为下一页
						 * Sting.valueOf();表示将Integer类型转换成String类型
						 */
						jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(this.pageIndex+1));
						//拼接下一页
						sf.append("<a href='"+jumpUrl+"'>下一页</a>");
					}
				/**
				 * 假设当前页码在尾页  当前页码=总页码
				 * 则"上一页"为当前页码-1
				 * 中间页(方法)
				 * "下一页"不能点击，拼接"下一页"
				 */
				}else if(this.pageIndex ==totalPageNum ){
					/**
					 * 设置上一页跳转路径，拼接"上一页"路径
					 * 跳转路径为提交地址将占位符"{0}"替换成"当前页码"-1,则为上一页
					 */
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(this.pageIndex-1));
					//拼接上一页
					sf.append("<a href='"+jumpUrl+"'>上一页</a>");
					
					/**
					 * 计算中间页码
					 * 带入参数：拼接字符串,总页码值
					 */
					calcMiddlepage(sf,totalPageNum);
					
					
					//下一页不能点击，拼接"下一页"
					sf.append("<span class='disabled'>下一页</span>");
				/**
				 *假如当前页码既不在首页也不在尾页 
				 *设置上一页跳转路径，拼接"上一页"路径
				 *中间页(方法)
				 *设置下一页跳转的路径，拼接'下一页'路径
				 */
				}else{
					/**
					 * 设置上一页跳转路径，拼接"上一页"路径
					 * 跳转路径为提交地址将占位符"{0}"替换成"当前页码"-1,则为上一页
					 */
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(this.pageIndex-1));
					//拼接上一页
					sf.append("<a href='"+jumpUrl+"'>上一页</a>");
					
					
					/**
					 * 计算中间页码
					 * 带入参数：拼接字符串,总页码值
					 */
					calcMiddlepage(sf,totalPageNum);
					
					/**
					 * 设置下一页跳转路径，拼接'下一页'路径
					 * 跳转路径为提交地址将占位符"{0}"替换成"当前页码"+1,则为下一页
					 * Sting.valueOf();表示将Integer类型转换成String类型
					 */
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(this.pageIndex+1));
					//拼接下一页
					sf.append("<a href='"+jumpUrl+"'>下一页</a>");	
				}
				/**
				 * 准备将数据写回至客户端
				 * 计算每页的开始以及结束行号
				 * 开始行号：(当前页码 -1) * pageSize + 1;当当前页码为1时,开始行号为1；当当前页码为2时，下一个开始页码为11
				 * 总共recordCount条记录,当前显示startSize-endSize条记录
				 */
				int startSize = (this.pageIndex - 1) * pageSize + 1;
				/**
				 * 判断当前页码是否等于总页码，
				 * 如果等于，结束行号为总记录数，
				 * 如果不等，结束行号为当前页码*每页显示数量
				 */
				int endSize = this.pageIndex == totalPageNum ? this.recordCount : this.pageIndex * this.pageSize;
				//将拼装号的数据写回客户端
				write.write("<table width='100%' class='"+this.pageStyle+"'><tr><td align='center'>"+sf.toString()+"跳转到<input type='text' size='4' id='jumpNum'/><input type='button' value='跳转' id='jumpbtn'/></td></tr>");
				write.write("<tr><td align='center'>总共<font color='red'>"+this.recordCount+"</font>条记录,当前显示"+startSize+"-"+endSize+"条记录</td></tr></table>");
			
				//使用js调用函数
				write.write("<script type='text/javascript'>");
				
				write.write("document.getElementById('jumpbtn').onclick = function(){");
				write.write("var value = document.getElementById('jumpNum').value;");
				write.write("if(!/^[1-9]\\d*$/.test(value)||value > "+totalPageNum+"){");
				write.write("alert('请输入[1-"+totalPageNum+"]之间的页码值！');");
				write.write("}else{");
				// index.action?pageIndex = {0}
				write.write("var submiturl = '"+this.submitUrl+"';");
				write.write("submiturl = submiturl.replace('"+this.TAG+"',value);");
				write.write("window.location = submiturl;");
				
				write.write("}");
				
				write.write("}");
				write.write("</script>");
				
			}else{
				/**
				 * this.recordCount <= 0
				 * 如果总记录数小于0，即没有数据
				 */
				write.write("<table align='center' width='100%' class='"+this.pageStyle+"'><tr align='center'><td align='center'>总共<font color='red'>0</font>条记录,当前显示0-0条记录</td></tr></table>");				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		return super.doStartTag();
	}

	/**
	 * 计算中间页码
	 * @param sf
	 * @param totalPageNum
	 */
	private void calcMiddlepage(StringBuffer sf, int totalPageNum) {
		//定义跳转路径
		String jumpUrl ="";
		
		/**
		 * 假设总共的页码数小于10,则所有的页码全部显示
		 * totalPageNum <= 10
		 * 如：上一页  1 2 3 4 5 6 7 8 9 10 下一页
		 */
		if(totalPageNum <= 10){
			//循环获取所有的页码
			for(int i = 1;i <= totalPageNum;i++){
				//判断如果是在当前页就不能点击
				if(i == this.pageIndex){
					sf.append("<span class='current'>"+i+"</span>");
				/**
				 * 如果不是当前页，每页都可以点击
				 * 设置跳转路径，拼接
				 */
				}else{
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(i));
					sf.append("<a href='"+jumpUrl+"'>"+i+"</a>");
				}
			}
		/**
		 * 假设当前页码靠近首页 如:上一页 1 2 3 4 5 6 7 8 9 ... 100 下一页
		 * 假设页码数超过10的时候，认为页码数过多，需要拼装"..."
		 * 如当前页码小于8页的时候，后面再跟第9页
		 */
		}else if(this.pageIndex <= 8){
			//循环获取所有的页码,i<=9表示往后显示一页
			for(int i = 1;i <= 9;i++){
				//判断如果是在当前页就不能点击
				if(i == this.pageIndex){
					sf.append("<span class='current'>"+i+"</span>");
				/**
				 * 如果不是当前页，每页都可以点击
				 * 设置跳转路径，拼接
				 */
				}else{
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(i));
					sf.append("<a href='"+jumpUrl+"'>"+i+"</a>");
				}
			}
			//拼装省略号
			sf.append("...");
			
			//拼装尾页 即总页码totalPageNum
			jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(totalPageNum));
			sf.append("<a href='"+jumpUrl+"'>"+totalPageNum+"</a>");
		/**
		 * 假设当前页码靠近尾页
		 * 如：上一页 1 ... 91 92 93 94 95 96 97 98 99 100 下一页
		 * 条件是：当前页+8>=totalPageNum 总页数
		 */
		}else if(this.pageIndex + 8 >= totalPageNum){
			//拼装首页(第一页) 将index.action?pageIndex={0}中的"{0}"占位符换成1
			jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(1));
			//设置跳转  index.action?pageIndex= 1
			sf.append("<a href='"+jumpUrl+"'>"+1+"</a> ");
			
			//拼装省略号
			sf.append("...");
			
			/**
			 * 设置靠近尾页数据，for循环所有的页码，初始值为从后往前第9位，
			 */
			for(int i=totalPageNum-9;i<=totalPageNum;i++){
				//当前页码不可点击
				if(i==this.pageIndex){
					sf.append("<span class='current'>"+i+"</span>");
				}else{
					//不是当前页码，都可以点击
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(i));
					//设置跳转  index.action?pageIndex= 1
					sf.append("<a href='"+jumpUrl+"'>"+i+"</a> ");
				}
			}
		/**
		 * 当前页码在中间
		 * 如：1 ... 41 42 43 44 45 46 47 48 49 ... 100 
		 * 比如当前页码为45,前后各显示4个，
		 * 拼装首页，中间，和尾页
		 */
		}else{
			//拼装首页
			jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(1));
			sf.append("<a href='"+jumpUrl+"'>"+1+"</a>");
			
			//拼装省略号
			sf.append("...");
			
			/**
			 * 拼装中间页码
			 */
			for(int i = this.pageIndex-4;i <=this.pageIndex+4;i++){
				//当前页码不可点击
				if(i==this.pageIndex){
					sf.append("<span class='current'>"+i+"</span>");
				//不是当前页都可以点击
				}else{
					jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(i));
					sf.append("<a href='"+jumpUrl+"'>"+i+"</a>");
				}
			}
			//拼接后面的省略号
			sf.append("...");
			
			//拼装尾页 即总页码totalPageNum
			jumpUrl = this.submitUrl.replace(this.TAG, String.valueOf(totalPageNum));
			sf.append("<a href='"+jumpUrl+"'>"+totalPageNum+"</a>");
			
		}
		
	}

	public Integer getPageIndex() {
		return pageIndex;
	}


	public void setPageIndex(Integer pageIndex) {
		if(pageIndex==null){
        	pageIndex = 1;
        }
		this.pageIndex = pageIndex;
	}


	public Integer getPageSize() {
		return pageSize;
	}


	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}


	public Integer getrecordCount() {
		return recordCount;
	}


	public void setrecordCount(Integer recordCount) {
		this.recordCount = recordCount;
	}


	public String getSubmitUrl() {
		return submitUrl;
	}


	public void setSubmitUrl(String submitUrl) {
		this.submitUrl = submitUrl;
	}

	public String getPageStyle() {
		return pageStyle;
	}

	public void setPageStyle(String pageStyle) {
		this.pageStyle = pageStyle;
	}

	
}
